<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>3. DockerFile定制镜像 | Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="简单介绍DockerFile定制定向的目的是为了将完成开发的应用以及其运行环境，打包称一个可以在docker容器中进行运行的Docker Image 容器镜像，这样以便于一次打包多次运行多平台运行的效果。DockerFile 是一个文本文件其内部包含了一条一条的指令，每一条指令构建一层。因此每一条指令的内容就是描述该层该如何构建。备注：当我们启动容器，并且想进入容器的时候，可以使用如下命令：  d">
<meta property="og:type" content="article">
<meta property="og:title" content="3. DockerFile定制镜像">
<meta property="og:url" content="http://yoursite.com/2020/02/10/3.DockerFile%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="简单介绍DockerFile定制定向的目的是为了将完成开发的应用以及其运行环境，打包称一个可以在docker容器中进行运行的Docker Image 容器镜像，这样以便于一次打包多次运行多平台运行的效果。DockerFile 是一个文本文件其内部包含了一条一条的指令，每一条指令构建一层。因此每一条指令的内容就是描述该层该如何构建。备注：当我们启动容器，并且想进入容器的时候，可以使用如下命令：  d">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2020-02-10T10:00:28.693Z">
<meta property="article:modified_time" content="2020-02-29T08:45:57.990Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/myblog/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/myblog/css/style.css">

<meta name="generator" content="Hexo 4.2.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/myblog/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/myblog/">Home</a>
        
          <a class="main-nav-link" href="/myblog/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/myblog/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-3.DockerFile定制镜像" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/myblog/2020/02/10/3.DockerFile%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F/" class="article-date">
  <time datetime="2020-02-10T10:00:28.693Z" itemprop="datePublished">2020-02-10</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      3. DockerFile定制镜像
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="简单介绍"><a href="#简单介绍" class="headerlink" title="简单介绍"></a>简单介绍</h3><p>DockerFile定制定向的目的是为了将完成开发的应用以及其运行环境，打包称一个<br>可以在docker容器中进行运行的Docker Image 容器镜像，这样以便于一次打包多次运行<br>多平台运行的效果。<br>DockerFile <strong>是一个文本文件</strong>其内部包含了一条一条的指令，每一条指令构建一层。因此<br>每一条指令的内容就是描述该层该如何构建。<br>备注：当我们启动容器，并且想进入容器的时候，可以使用如下命令：</p>
<blockquote>
<p>dcoker exec -it tomcat容器的id bash</p>
</blockquote>
<p>该命令可以让我们 以交互的方式进入到 tomcat容器内部，对容器内部的内容进行修改或者查看。但是此时由于<br>进入了docker的tomcat容器中，所以有些命令是不能使用的，但是最基本的命令还是可以使用的例如<br>ls 或者 echo等命令。<br>此时使用命令：</p>
<blockquote>
<p>cd/webapp/Root<br>echo “Hello World Tomcat!” &gt;&gt; index.jsp</p>
</blockquote>
<p>在index.jsp页面中追加Hello World Tomcat! 这段文字，然后在查看。</p>
<p><u>以上的过程是启动容器后并在容器中进行修改的一个过程，但是这样比较麻烦，此时我们可以创建DockerFile<br>文件，对容器进行修改，然后在启动容器，这样就直接就可以生成一个达到我们使用要求的容器。</u></p>
<h3 id="创建一个简单的DockerFile文件例子"><a href="#创建一个简单的DockerFile文件例子" class="headerlink" title="创建一个简单的DockerFile文件例子"></a>创建一个简单的DockerFile文件例子</h3><p>例子如下：创建一个目录，并在该目录下创建一个dockerfile文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir mydockerfile </span><br><span class="line">cd mydockerfile </span><br><span class="line">vi Dockerfile</span><br></pre></td></tr></table></figure>
<p>其内容为：</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">From</span> tomcat</span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> <span class="built_in">echo</span> <span class="string">"Hello World Tomcat!"</span> &gt; /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT/index.html</span></span><br></pre></td></tr></table></figure>

<p>From 制定基础的镜像，该镜像继承了tomcat镜像的所有特性，且所有的dockerfile文件第一句都是From制定基础镜像。<br>RUN 该指令是用来执行命令行指令的，由于命令行强大，run指令在定制镜像的时候是常用的一个指令。其格式通常有两种<br>一种是 <u><b> shell格式 </b></u>另外一种是 <u><b> exec格式 </b></u>   </p>
<blockquote>
<p>shell 格式 ：RUN &lt;命令&gt; ，就像直接在命令行中输入命令是一样的。在简介中写入的那些命令你就这种方式。</p>
</blockquote>
<blockquote>
<p>exec 格式： RUN [“可执行文件”,”参数1”,”参数2”] 这更像是函数调用中的格式。 </p>
</blockquote>
<p>定制完Dockerfile之后就可以创建镜像了。 </p>
<blockquote>
<p>docker build -t myshop .   myshop 表示的是标签这个可以自己随意修改，而 . 则表示的是当前目录为了告诉 dockerfile文件在何处</p>
</blockquote>
<p>上面这个是对容器中的文件进行修改，但是如果要先删除在修改呢。就需要使用WORKDIR 命令去切换工作目录才行。然而如果切换了目录进行了操作之<br>后，还需要切换回tomcat的运行目录才行，所以需要对上面的dockerfile文件进行修改。<u>需要只得注意的是 . 代表的是相对路径的根目录，表示的<br>是当前Dockerfile 文件所在的目录，而该目录也会在docker build 之后 背会docker clinet 压缩然后发送给docker server 进行解压然<br>后进行具体的docker操作。</u></p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">From</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr *</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> <span class="built_in">echo</span> <span class="string">"Hello World Tomcat!"</span> &gt; /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT/index.html</span></span><br></pre></td></tr></table></figure>
<p>然后在运行容器即可：</p>
<blockquote>
<p>docker run -p 8080:8080 myshop </p>
</blockquote>
<p>之后该运行成功的镜像，无论放到什么环境的docker中运行之后都是这种效果。</p>
<h3 id="DockerFile的指令详解"><a href="#DockerFile的指令详解" class="headerlink" title="DockerFile的指令详解"></a>DockerFile的指令详解</h3><p>dockerfile 指令除了有上面介绍的From，Run，WORKDIR还有其他的如：copy[复制文件] ，ADD[更高级的复制文件]，CMD[容器启动命令]，<br>entrypoint【入口点】env【设置环境变量】，valume【定义匿名卷】expose【报漏端口】，workdir【制定工作目录】  </p>
<h5 id="【WORKDIR】"><a href="#【WORKDIR】" class="headerlink" title="【WORKDIR】"></a>【<strong>WORKDIR</strong>】</h5><p>使用该命令来指定docker的工作目录（相当于cd的意思）。当执行过这个命令之后，以后各层的命令所执行的目录就是该语句指定的目录<br>如果该目录不存在，那么就会为你创建该目录。每一个RUN都是启动了一个容器。</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> my-shop-web-admin-1.0.1.zip . </span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> unzip my-shop-web-admin-1.0.1.zip</span></span><br></pre></td></tr></table></figure>
<p>备注：copy 命令就是将该my-shop-web-admin-1.0.1.zip 拷贝到 . 也就是docker的上下文中。</p>
<p>但是执行万上面的命令的时候并不能成功创建并运行docker，因为拷贝过去的项目里面包含了ROOT目录中已经存在的东西，所以需要预先将ROOT目录<br>下面的东西给删除掉，所以需要修改命令如下。</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr * </span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> my-shop-web-admin-1.0.1.zip . </span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> unzip my-shop-web-admin-1.0.1.zip</span></span><br></pre></td></tr></table></figure>
<p>但是此时还是有问题，需要把无用的zip文件给删除掉。</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr * </span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> my-shop-web-admin-1.0.1.zip . </span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> unzip my-shop-web-admin-1.0.1.zip</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr my-shop-web-admin-1.0.1.zip</span></span><br></pre></td></tr></table></figure>
<p>如果需要运行tomcat依旧需要将工作目录切换回镜像本身的工作目录usr/local/tomcat才行。</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr * </span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> my-shop-web-admin-1.0.1.zip . </span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> unzip my-shop-web-admin-1.0.1.zip</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr my-shop-web-admin-1.0.1.zip</span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat</span></span><br></pre></td></tr></table></figure>
<h5 id="【ADD】"><a href="#【ADD】" class="headerlink" title="【ADD】"></a>【ADD】</h5><p>ADD是一个更加高级的Add指令的格式和性质与COPY基本上是一致的。但是比copy更加强大，算是一个加强版的copy吧。  </p>
<ol>
<li>这个add可以添加一个URL连接，可以拷贝网络上面的东西到docker中。在这种情况下docker引擎会试图去下载一个<br>这个连接的文件，然后放置到目标路径中去。下载后文件的全县自动设置为600（linux权限的数字表示法）如果不想要<br>其他的权限，那么就需要增加一个RUN命令去修改。  </li>
<li>但是如果add的url下载的是一个zip的话，仍然需要额外增加一层RUN命令去解压这个zip包。所以不如直接使用RUN命令<br>然后附带使用wget或者curl工具下载，处理权限，解压缩然后清理无用文件更加的合适，所以并不推荐使用add。  </li>
<li>如果源文件是一个tar的压缩文件的话，并且是压缩格式为gzip，zip2以及xz的情况下。ADD指令将会自动解压缩这个压缩<br>文件到 目标路径  </li>
<li>在copy和add的选择的时候，遵循这个原则，所有文件的复制均使用copy命令，仅仅在需要自动解压缩的场合使用add。<h5 id="【EXPOSE】"><a href="#【EXPOSE】" class="headerlink" title="【EXPOSE】"></a>【EXPOSE】</h5>格式为 EXPOSE 端口1 [端口2….]<br>expose指令是运行时候容器提供的服务端口，这只是一个声明。在运行的时候，并不会因为这个声明，应用就会开启这个端口的<br>服务。在dockerfile中写入这么一个声明的信息有两个好处  </li>
<li>帮助镜像使用者理解这个镜像服务的守护端口，以方便配置映射。</li>
<li>运行时使用随机端口映射的时候也就是 docker run -p时，会自动随机映射Expose声明的端口。<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> tomcat</span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat/webapps/ROOT</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr * </span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> my-shop-web-admin-1.0.1.zip . </span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> unzip my-shop-web-admin-1.0.1.zip</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> rm -fr my-shop-web-admin-1.0.1.zip</span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /usr/<span class="built_in">local</span>/tomcat </span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8080</span></span><br></pre></td></tr></table></figure>
<h5 id="【CMD指令】"><a href="#【CMD指令】" class="headerlink" title="【CMD指令】"></a>【CMD指令】</h5>CMD指令和RUN指令的格式是一样的。也是两种格式：  <blockquote>
<p>shell格式：CMD &lt;命令&gt;<br>exec格式：CMD [“可执行文件”,”参数1”,”参数2”]<br>参数列表格式： CMD [“参数1”,”参数2”……] 在指定了ENTRYPOINT指令之后，用CMD指定具体的参数</p>
</blockquote>
</li>
</ol>
<p>备注：Dockerfile 只有那么几个命令，<u>但是难的在于shell的编写。之前介绍容器的时候就说过docker不是虚拟机，<br>每一个容器就是一个进程。既然是进程，那么在启动容器的时候就需要指定所运行的程序以及参数。CMD指令就是用于指定<br>默认容器主进程的启动命令。</u>  </p>
<blockquote>
<p>EXPOSE 所暴漏的端口号，给宿主机提供了一个访问容器的端口映射途径，举例Tomcat 来说人员访问会首先访问宿主机然后<br>再通过宿主机访问docker容器，而EXPOSE 的这个端口则提示出宿主机如果要访问容器的话，直接连接容器暴漏出来的这个<br>端口即可。<br>执行  docker run -p 80:8080 tomcat<br>其中左侧的 80 是宿主机提供给访问者的访问端口，而8080 则是docker容器所暴漏出来的端口号。</p>
</blockquote>
<p>备注：如果不涉及到镜像的定制，那么就只需要会使用Docker的三剑客如Compose即可，但是如果需要定制就需要会dockerfile</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/02/10/3.DockerFile%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F/" data-id="ck6p0boqr0000tjd1fnpd5fqy" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/myblog/2020/02/23/4.Docker%20%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          4. Docker的常用命令
        
      </div>
    </a>
  
  
    <a href="/myblog/2020/02/05/2.Java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E7%AC%94%E8%AE%B0/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">2. Java并发编程笔记</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2020/02/">February 2020</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/myblog/2020/02/29/6.Docker%20%E4%B8%89%E5%89%91%E5%AE%A2/">6. Docker三剑客</a>
          </li>
        
          <li>
            <a href="/myblog/2020/02/28/5.Docker%20%E5%AE%B9%E5%99%A8%E6%95%B0%E6%8D%AE%E6%8C%81%E4%B9%85%E5%8C%96/">5. Docker容器数据持久化</a>
          </li>
        
          <li>
            <a href="/myblog/2020/02/23/4.Docker%20%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/">4. Docker的常用命令</a>
          </li>
        
          <li>
            <a href="/myblog/2020/02/10/3.DockerFile%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F/">3. DockerFile定制镜像</a>
          </li>
        
          <li>
            <a href="/myblog/2020/02/05/2.Java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E7%AC%94%E8%AE%B0/">2. Java并发编程笔记</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2020 John Doe<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/myblog/" class="mobile-nav-link">Home</a>
  
    <a href="/myblog/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/myblog/fancybox/jquery.fancybox.css">

  
<script src="/myblog/fancybox/jquery.fancybox.pack.js"></script>




<script src="/myblog/js/script.js"></script>




  </div>
</body>
</html>